package sk.fiit.vppj.eventmanager.gui.administrator;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.imageio.ImageIO;

import net.sourceforge.barbecue.Barcode;
import net.sourceforge.barbecue.BarcodeException;
import net.sourceforge.barbecue.BarcodeFactory;
import net.sourceforge.barbecue.output.OutputException;
import sk.fiit.vppj.eventmanager.core.ConfigManager;
import sk.fiit.vppj.eventmanager.data.User;

public class IdCard {
	private User user = null;
	public IdCard(User user) {
		this.user = user;
		setTemplate( user.getClazz() );
		setBarcodeNumber( createBarcodeNumber( user.getId() ) );

	}
	
	private String barcode = null;
	private String templateAbsolutePath = null;
	private static final int PER_LINE = 30;
	private final static Logger log = Logger.getLogger( IdCardPrinter.class.getName() );

	private void setBarcodeNumber(String barcode) {
		this.barcode = barcode;
	}

	private String processName(String name) {
		int totalLength = name.length();

		StringBuilder processedLine = new StringBuilder( 30 );
		StringBuilder processedName = new StringBuilder( totalLength * 2 );

		String[] parts = name.split( " " );

		for ( String word : parts ) {
			if( ( processedLine.length() + word.length() ) > PER_LINE ) {
				processedName.append( processedLine.toString() );
				processedName.append( '\n' );
				processedLine.delete( 0, processedLine.length() );
			}
			processedLine.append( word );
			processedLine.append( ' ' );

		}
		if( processedLine.length() > 0 ) {
			processedName.append( centerLine( processedLine.toString() ) );
		}
		return processedName.toString();
	}

	private String centerLine(String input) {
		StringBuilder line = new StringBuilder( PER_LINE );
		int numSpaces = ( PER_LINE - input.length() ) / 2;
		for ( int i = 0; i < numSpaces; i++ ) {
			line.append( " " );
		}
		line.append( input );
		for ( int i = 0; i < numSpaces; i++ ) {
			line.append( " " );
		}

		return line.toString();
	}

	private void setTemplate(String clazz) {
		String path = null;
		if( clazz.equals( "participant" ) ) {
			path = this.getClass().getResource( "/resources/templates/participant.jpg" ).getPath();
		}
		else if( clazz.equals( "supervisor" ) ) {
			path = this.getClass().getResource( "/resources/templates/supervisor.jpg" ).getPath();
		}
		else if( clazz.equals( "judge" ) ) {
			path = this.getClass().getResource( "/resources/templates/judge.jpg" ).getPath();
		}
		else if( clazz.equals( "volunteer" ) ) {
			path = this.getClass().getResource( "/resources/templates/volunteer.jpg" ).getPath();
		}
		this.templateAbsolutePath = path;
	}

	private BufferedImage getTemplate() {
		try {
			return ImageIO.read( new File( this.templateAbsolutePath ) );
		}
		catch ( IOException e ) {
			log.log( Level.WARNING, "Can't load template for creating IdCard", e );
			e.printStackTrace();
		}
		return null;
	}

	BufferedImage getCard() {
		BufferedImage template = null;
		try {
			template = getTemplate();
			String photoLocation = new ConfigManager().getProperties().get( "photoLocation" ).toString();
			BufferedImage photo = ImageIO.read( new File( photoLocation + "\\" + user.getPhotoPortrait() ) );

			Graphics2D templateGraphics = template.createGraphics();
			templateGraphics.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON );
			templateGraphics.drawImage( photo, 260, 330, 300, 400, null );
			
			Font font2 = new Font( Font.MONOSPACED, Font.BOLD, 32 );
			templateGraphics.setFont( font2 );
			templateGraphics.setColor( Color.BLACK );
			drawString( templateGraphics, user.getGroupName(), 100, 350 );

			Font font3 = new Font( Font.MONOSPACED, Font.BOLD, 32 );
			templateGraphics.setFont( font3 );
			templateGraphics.setColor( Color.BLACK );
			drawString( templateGraphics, user.getGroupName(), 600, 350 );
			
			Font font = new Font( Font.MONOSPACED, Font.BOLD, 32 );
			templateGraphics.setFont( font );
			templateGraphics.setColor( Color.BLACK );
			drawString( templateGraphics, processName( user.getName() ), 150, 750 );
			
			
			getBarcode( barcode ).draw( templateGraphics, 220, 860 );
			templateGraphics.dispose();
		}
		catch ( IOException e ) {
			log.log( Level.SEVERE, "Can't create id card", e );
			e.printStackTrace();
		}
		catch ( OutputException e ) {
			log.log( Level.SEVERE, "Creating barcode failed", e );
			e.printStackTrace();
		}

		return template;
	}

	private void drawString(Graphics g, String text, int x, int y) {
		for ( String line : text.split( "\n" ) )
			g.drawString( line, x, y += g.getFontMetrics().getHeight() );
	}


	private Barcode getBarcode(String number) {
		Barcode barcode = null;
		try {
			barcode = BarcodeFactory.createCode128( number );
			barcode.setBarWidth( 3 );
			barcode.setResolution( 300 );

			return barcode;

		}
		catch ( BarcodeException e ) {
			log.log( Level.SEVERE, "Can't create barcode", e );
		}

		return null;

	}

	private String createBarcodeNumber(int number) {
		StringBuilder barcode = new StringBuilder( 10 );
		for ( int i = 0; i < 10 - String.valueOf( number ).length(); i++ ) {
			barcode.append( "0" );
		}
		return barcode.append( String.valueOf( number ) ).toString();
	}
}
